package com.fyb.basic.lock.thread;

/**
 * 如何通过两个线程交替打印大写和小写字母
 * 输出结果：AbCdEfGhIjKlMnOpQrStUvWxYz[
 */
public class AlternateLetterPrinting {
    // 静态锁对象，用于线程同步
    private static final Object lock = new Object();
    // 当前要打印的字母，初始值为 'A'
    private static char currentLetter = 'A';
    // 布尔变量，表示是否应该打印大写字母
    private static boolean printUpperCase = true;

    public static void main(String[] args) {
        // 创建线程用于打印大写字母
        Thread upperCasePrinter = new Thread(() -> printLetter(true));
        // 创建线程用于打印小写字母
        Thread lowerCasePrinter = new Thread(() -> printLetter(false));

        // 启动大写字母打印线程
        upperCasePrinter.start();
        // 启动小写字母打印线程
        lowerCasePrinter.start();
    }

    /**
     * 打印字母的方法
     * @param isUpperCaseThread 指示当前线程是否打印大写字母
     */
    private static void printLetter(boolean isUpperCaseThread) {
        // 使用无限循环来打印字母，直到条件不满足
        while (true) {
            synchronized (lock) {
                // 如果当前字母超出 'Z'，则退出循环并唤醒其他线程
                if (currentLetter > 'Z') {
                    lock.notifyAll();
                    break;
                }

                // 当不是当前线程的打印机会时，等待
                while (printUpperCase != isUpperCaseThread) {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        // 设置线程的中断状态并返回
                        Thread.currentThread().interrupt();
                        return;
                    }
                }

                // 打印当前字母，如果是大写线程则打印大写字母，否则打印小写字母
                if (isUpperCaseThread) {
                    System.out.print(currentLetter);
                } else {
                    System.out.print(Character.toLowerCase(currentLetter));
                }

                // 切换打印大小写标志
                printUpperCase = !printUpperCase;
                // 递增当前字母
                currentLetter++;

                // 唤醒其他线程
                lock.notifyAll();
            }
        }
    }
}

